package com.irdstudio.efp.flow.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.irdstudio.efp.flow.common.vo.AprvUserVO;
import com.irdstudio.efp.flow.service.dao.FlowAprvUserDao;
import com.irdstudio.efp.flow.service.dao.InstFlowProcessDao;
import com.irdstudio.efp.flow.service.domain.BizFlowProcess;
import com.irdstudio.efp.flow.service.domain.InstFlowProcess;
import com.irdstudio.efp.flow.service.facade.InstFlowProcessService;
import com.irdstudio.efp.flow.service.vo.FlowAprvUserInqVO;
import com.irdstudio.efp.flow.service.vo.InstFlowProcessVO;
import com.irdstudio.basic.framework.core.base.FrameworkService;


/**
 * 
 * 
 * 
 * @author Cytus_
 * @since 2018年5月8日 下午7:56:24
 * @version 1.0
 *
 */
@Service("instFlowProcessService")
public class InstFlowProcessServiceImpl implements InstFlowProcessService, FrameworkService {
	
	private static Logger logger = LoggerFactory.getLogger(InstFlowProcessServiceImpl.class);
	
	
	@Autowired
	private InstFlowProcessDao instFlowProcessDao;
	
	@Autowired
	private FlowAprvUserDao flowAprvUserDao;
	
	

	public InstFlowProcessVO queryByNodeInstanceId(String instanceId) {
		logger.debug("根据节点示例号:"+ instanceId +"查询信息开始......");
		InstFlowProcessVO processvo = null;
		try {
			InstFlowProcess process = this.instFlowProcessDao.queryByNodeInstanceId(instanceId);
			processvo = beanCopy(process, new InstFlowProcessVO());
			logger.debug("根据节点示例号:"+ instanceId +"查询信息结束......");
		} catch (Exception e) {
			logger.error("根据节点示例号:"+ instanceId +"查询信息出现异常!", e);
		}
		return processvo;
	}

	public int insertInstFlowProcess(InstFlowProcessVO vo) {
		logger.debug("新增数据开始......");
		int num = 0;
		InstFlowProcess process = beanCopy(vo, new InstFlowProcess());
		try {
			num = this.instFlowProcessDao.insertInstFlowProcess(process);
			logger.debug("新增数据结束......");
		} catch (Exception e) {
			logger.error("新增数据出现异常!", e);
			num = -1;
		}
		return num;
	}

	public int updateNodeStatusByInstNodeId(InstFlowProcessVO vo) {
		logger.debug("根据节点流水号:"+ vo.getInstNodeId() +"更新状态："+ vo.getInstNodeState() +"开始......");
		int num = 0;
		InstFlowProcess process = beanCopy(vo, new InstFlowProcess());
		try {
			num = this.instFlowProcessDao.updateNodeStatusByInstNodeId(process);
			logger.debug("根据节点流水号:"+ vo.getInstNodeId() +"更新状态："+ vo.getInstNodeState() +"结束......");
		} catch (Exception e) {
			logger.error("根据节点流水号:"+ vo.getInstNodeId() +"更新状态："+ vo.getInstNodeState() +"出现异常!", e);
			num = -1;
		}
		return num;
	}

	
	public int updateApproveInfoByNodeInstId(InstFlowProcessVO vo) {
		logger.debug("根据节点流水号:"+ vo.getInstNodeId() +"更新审批信息开始......");
		int num = 0;
		InstFlowProcess process = beanCopy(vo, new InstFlowProcess());
		try {
			num = this.instFlowProcessDao.updateApproveInfoByNodeInstId(process);
			logger.debug("根据节点流水号:"+ vo.getInstNodeId() +"更新审批信息结束......");
		} catch (Exception e) {
			logger.error("根据节点流水号:"+ vo.getInstNodeId() +"更新审批信息出现异常!", e);
			num = -1;
		}
		return num;
	}

	
	public int updateAprvUserInfoByNodeInstId(InstFlowProcessVO vo) {
		logger.debug("根据节点流水号:"+ vo.getInstNodeId() +"更新审批人信息开始......");
		int num = 0;
		InstFlowProcess process = beanCopy(vo, new InstFlowProcess());
		try {
			num = this.instFlowProcessDao.updateAprvUserInfoByNodeInstId(process);
			logger.debug("根据节点流水号:"+ vo.getInstNodeId() +"更新审批人信息结束......");
		} catch (Exception e) {
			logger.error("根据节点流水号:"+ vo.getInstNodeId() +"更新审批人信息出现异常!", e);
			num = -1;
		}
		return num;
	}

	public List<String> queryDissatisfyAprvMaxUsers(FlowAprvUserInqVO vo) {
		logger.debug("节点ID："+ vo.getBizNodeId() +", 事件ID："+ vo.getBizEventId() +", 节点最大同时存在处理任务数："+ vo.getMaxAprvNum() +", 查询不满足条件的人员信息开始......");
		List<String> list = null;
		try {
			list = this.flowAprvUserDao.queryDissatisfyAprvMaxUsers(vo);
			logger.debug("节点ID："+ vo.getBizNodeId() +", 事件ID："+ vo.getBizEventId() +", 节点最大同时存在处理任务数："+ vo.getMaxAprvNum() +", 查询不满足条件的人员信息结束, 查询结果为:"+ list);
		} catch (Exception e) {
			logger.error("节点ID："+ vo.getBizNodeId() +", 事件ID："+ vo.getBizEventId() +", 节点最大同时存在处理任务数："+ vo.getMaxAprvNum() +", 查询不满足条件的人员信息出现异常!", e);
		}
		return list;
	}

    @SuppressWarnings("unchecked")
    @Override
    public List<InstFlowProcessVO> queryAllByBizSerno(String bizSerno) {
        logger.debug("事件实例号(业务流水号)："+ bizSerno +"查询所有节点信息开始.....");
        List<InstFlowProcessVO> vos = null;
        try {
            List<InstFlowProcess> processes = this.instFlowProcessDao.queryAllByBizSerno(bizSerno);
            vos = (List<InstFlowProcessVO>) beansCopy(processes, InstFlowProcessVO.class);
            logger.debug("事件实例号(业务流水号)："+ bizSerno +"查询所有节点信息结束.....");
        } catch (Exception e) {
            logger.error("事件实例号(业务流水号)："+ bizSerno +"查询所有节点信息出现异常!", e);
        }
        return vos;
    }

    @Override
    public List<String> queryCanClaimNodes(String userId, List<String> dutyCodes) {
        logger.debug("用户编号:"+ userId +",岗位编号:"+ dutyCodes +"查询可以认领的节点id开始......");
        List<String> list = null;
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("dutyCodes", dutyCodes);
            List<BizFlowProcess> processes = this.flowAprvUserDao.queryCanClaimNodes(params);
            if (Objects.nonNull(processes) && !processes.isEmpty()) {
                List<Map<String, Object>> maxTask = this.flowAprvUserDao.queryMaxTaskNum(userId);
                if (Objects.nonNull(maxTask) && !maxTask.isEmpty()) {
                    for (Map<String, Object> task : maxTask) {
                        
                        for (int i = 0; i < processes.size(); i++) {
                            BizFlowProcess process = processes.get(i);
                            if (process.getBizEventId().equals(task.get("bizEventId")) && process.getBizNodeId().equals(task.get("bizNodeId"))
                                    && Integer.valueOf(String.valueOf(task.get("currNum"))) >= process.getMaxAprvNum() ) {
                                processes.remove(i);
                                break;
                            }
                        }
                        
                    }
                } 
            }
            
            list = processes.parallelStream().map(s -> s.getBizNodeId()).distinct().collect(Collectors.toList());
            
            logger.debug("用户编号:"+ userId +",岗位编号:"+ dutyCodes +"查询可以认领的节点id结束, 结果为:"+ list);
        } catch (Exception e) {
            logger.error("用户编号:"+ userId +",岗位编号:"+ dutyCodes +"查询可以认领的节点id出现异常!", e);
        }
        return list;
    }

    public Integer taskClaim(List<String> nodes, AprvUserVO aprvUserVo) {
        logger.debug("用户编号:"+ aprvUserVo.getUserId() +",认领的节点开始......");
        Integer rtl = null;
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("nodeIds", nodes);
            params.put("aprvUserVo", aprvUserVo);
            rtl = this.flowAprvUserDao.taskClaim(params);
            logger.debug("用户编号:"+ aprvUserVo.getUserId() +",认领的节点结束, 结果为："+ rtl);
        } catch (Exception e) {
            logger.debug("用户编号:"+ aprvUserVo.getUserId() +",认领的节点出现异常!", e);
        }
        return rtl;
    }

}
